package com.qjs.commom;

import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.TextNode;

public class JsonUtils {
	private  Logger log = Logger.getLogger(JsonUtils.class);

	    private final static ObjectMapper objectMapper;

	    static {
	    	objectMapper = new ObjectMapper();
	        // 如果为空则不输出
	        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
	        // 对于空的对象转json的时候不抛出错误
	        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
	        // 禁用序列化日期为timestamps
	        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
	        // 禁用遇到未知属性抛出异常
	   //     objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
	        // 视空字符传为null
	        objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

	        // 低层级配置
	        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
	        // 允许属性名称没有引号
	        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
	        // 允许单引号
	        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
	        // 取消对非ASCII字符的转码
	        objectMapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, false);

	        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
	        
	    }
	    
	    public static String toJsonString(Object object)
	    {
	      try
	      {
	        return objectMapper.writeValueAsString(object);
	      } catch (IOException ex) {
	        throw new RuntimeException(ex);
	      }
	    }
	   
	    public static void writeJsonString(Object object, Writer writer)
	    {
	      try
	      {
	    	  objectMapper.writeValue(writer, object);
	      } catch (IOException ex) {
	        throw new RuntimeException(ex);
	      }
	    }
	   
	    public static Map<?, ?> parseJson(String jsonString)
	    {
	      JsonNode jn = null;
	      try {
	        jn = objectMapper.readTree(jsonString);
	      } catch (IOException ex) {
	        ex.printStackTrace();
	      }
	      return (Map<?, ?>)JsonNodeToMap(jn);
	    }
	   
	    public static Object parseJson2MapOrList(String jsonString)
	    {
	      JsonNode jn = null;
	      try {
	        jn = objectMapper.readTree(jsonString);
	      } catch (IOException ex) {
	        ex.printStackTrace();
	      }
	      return JsonNodeToMap(jn);
	    }
	   
	    public static <T> T parseJson(String jsonString, Class<T> classType)
	    {
	      try {
	        return objectMapper.readValue(jsonString, classType);
	      } catch (Exception ex) {
	        ex.printStackTrace();
	      }return null;
	    }
	   
	    public static <T> T parseJson(String jsonString, TypeReference<T> typeReference)
	    {
	      try
	      {
	        return objectMapper.readValue(jsonString, typeReference);
	      } catch (Exception ex) {
	        ex.printStackTrace();
	      }return null;
	    }
	   
	    public static <T> T parseJsonT(String jsonString)
	    {
	      try
	      {
	        return objectMapper.readValue(jsonString, new TypeReference<Object>() { } );
	      }
	      catch (Exception ex) {
	        ex.printStackTrace();
	      }return null;
	    }
	   
	    public static <T> Map<?, ?> bean2Map(Object bean)
	    {
	      try
	      {
	        return (Map<?, ?>)objectMapper.convertValue(bean, Map.class);
	      } catch (Exception ex) {
	        ex.printStackTrace();
	      }return null;
	    }
	   
	    public static <T> T map2Bean(Map<?, ?> map, Class<T> clazz)
	    {
	      try
	      {
	        return objectMapper.convertValue(map, clazz);
	      } catch (Exception ex) {
	        ex.printStackTrace();
	      }return null;
	    }
	   
	    public static Object JsonNodeToMap(JsonNode root)
	    {
	      Map<String, Object> map = new LinkedHashMap<String, Object>();
	      if (root == null) {
	        return map;
	      }
	      if (root.isArray()) {
	        List<Object> list = new ArrayList<Object>();
	        for (JsonNode node : root) {
	          Object nmp = JsonNodeToMap(node);
	          list.add(nmp);
	        }
	        return list;
	      }if (root.isTextual()) {
	        try {
	          return ((TextNode)root).asText();
	        } catch (Exception e) {
	          return root.toString();
	        }
	      }
	      Iterator<?> iter = root.fields();
	      while (iter.hasNext()) {
	        @SuppressWarnings("rawtypes")
	      Map.Entry entry = (Map.Entry)iter.next();
	        String key = (String)entry.getKey();
	        JsonNode ele = (JsonNode)entry.getValue();
	        if (ele.isObject())
	          map.put(key, JsonNodeToMap(ele));
	        else if (ele.isTextual())
	          map.put(key, ((TextNode)ele).asText());
	        else if (ele.isArray())
	          map.put(key, JsonNodeToMap(ele));
	        else {
	          map.put(key, ele.toString());
	        }
	      }
	      return map;
	    }
	    
}
